package cn.yj.config;

import cn.yj.common.Enums;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Objects;

/**
 * 统一枚举处理类
 * 入库：enum.name()
 * 出库：enum.getMsg();
 *
 * @author 永健
 * @since 2021-05-08 06:27
 */
@MappedTypes(value = {Enums.IntegralWater.TYPE.class, Enums.IntegralWater.SOURCE.class,
        Enums.IntegralWater.STATUS.class, Enums.IntegralWater.SOURCE.class, Enums.Article.USER_VIEW_TYPE.class,
        Enums.TASK.STATUS.class})
public class EnumTypHandler<E extends Enum<?>> extends BaseTypeHandler<Enum<?>> {

    private static final Log LOGGER = LogFactory.getLog(EnumTypHandler.class);

    private Class<E> type;

    public EnumTypHandler(Class<E> type) {
        this.type = type;
    }


    @SuppressWarnings("Duplicates")
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Enum<?> parameter, JdbcType jdbcType) throws SQLException {
        try {
            if (jdbcType == null) {
                ps.setObject(i, parameter.name());
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    @Override
    public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
        if (null == rs.getObject(columnName) && rs.wasNull()) {
            return null;
        }
        return valueOf(rs.getObject(columnName));
    }

    @Override
    public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        if (null == rs.getObject(columnIndex) && rs.wasNull()) {
            return null;
        }
        return valueOf(rs.getObject(columnIndex));
    }

    @Override
    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        if (null == cs.getObject(columnIndex) && cs.wasNull()) {
            return null;
        }
        return valueOf(cs.getObject(columnIndex));
    }

    private E valueOf(Object value) {
        E[] es = this.type.getEnumConstants();
        for (E e : es) {
            if (Objects.equals(value, e.name())) {
                return e;
            }
        }
        return null;
    }
}
